package com.sgcc.pda.api;

import android.text.TextUtils;

import com.sgcc.pda.frme.protocol.ws.WSFrame;
import com.sgcc.pda.frme.protocol.ws.sendbean.EpcChoiceLabel2006;
import com.sgcc.pda.frme.protocol.ws.sendbean.EpcPanCun2005;
import com.sgcc.pda.frme.protocol.ws.sendbean.EpcReadDataParams2008;
import com.sgcc.pda.frme.protocol.ws.sendbean.EpcWriteDataParams2009;
import com.sgcc.pda.frme.protocol.ws.sendbean.GBChoiceLabel200D;
import com.sgcc.pda.frme.protocol.ws.sendbean.GBPanCun200C;
import com.sgcc.pda.frme.protocol.ws.sendbean.GBReadDataParams200F;
import com.sgcc.pda.frme.protocol.ws.sendbean.GBWriteDataParams2010;
import com.sgcc.pda.frme.protocol.ws.sendbean.MeterErrorParams;
import com.sgcc.pda.frme.protocol.ws.sendbean.MeterJXCWDataParams;
import com.sgcc.pda.frme.protocol.ws.sendbean.RS485Params;
import com.sgcc.pda.frme.protocol.ws.sendbean.SecretKeyParams;
import com.sgcc.pda.frme.protocol.ws.sendbean.SetMeterErrorParams;
import com.sgcc.pda.frme.protocol.ws.sendbean.SimParams;
import com.sgcc.pda.frme.protocol.ws.sendbean.ZaiboCheckParams;
import com.sgcc.pda.secretkey.SecretKeyManager;
import com.sgcc.pda.util.SPUtil;

import org.json.JSONException;
import org.json.JSONObject;


/**
 * 描 述：外设管理类
 * 作 者：王贵重
 * 时 间： 2020-03-04 11:40
 * 邮 箱：wanggz@bjhzwq.com
 * 版 本：1.0
 * 版 权：Copyright (c) 2019 remarkables-united.Co.Ltd. All rights reserved.
 */
public class WSManager implements IWSManager {

    private static class WSManagerHolder {
        //静态初始化器，由JVM来保证线程安全
        private static WSManager instance = new WSManager();
    }

    //私有化构造方法
    private WSManager() {
    }

    public static WSManager getInstance() {
        return WSManagerHolder.instance;
    }


    /**
     * 秘钥协商
     *
     * @return
     */
    public String secretkey() {
        //秘钥协商
        String frame = SecretKeyManager.getInstance().secretkey();
        return frame;
    }

    /**
     * 秘钥确认
     *
     * @param m2
     * @param mac2
     * @return
     */
    public boolean secretkeyConfirm(String m2, String mac2) {
        //秘钥协商
        boolean state = SecretKeyManager.getInstance().secretkeyConfirm(m2, mac2);
        return state;
    }

    //---------------------------------------外设通用grx-------------------------------------------------//


    private String buildWSFrameString(String address, int function, String data) {
        return WSFrame.builder().address(address).function(function).data(data).build().getFrameString();
    }

    private String buildWSFrameString(int function, String data) {
        String wsDeviceInfo = SPUtil.getWsDeviceInfo();
        //默认广播地址
        String address = "AAAAAAAAAAAA";
        try {
            JSONObject jsonObject = new JSONObject(wsDeviceInfo);
            address = jsonObject.getString("deviceId");
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return buildWSFrameString(address, function, data);
    }

    private String buildWSFrameString(int function) {
        return buildWSFrameString(function, "");
    }

    private String buildWSFrameString(int type, int function) {
        return buildWSFrameString(type, function, "");
    }

    private String buildWSFrameString(int type, int function, String data) {
        String wsDeviceInfo = SPUtil.getWsDeviceInfo();
        //默认广播地址
        String address = "AAAAAAAAAAAA";
        try {
            JSONObject jsonObject = new JSONObject(wsDeviceInfo);
            address = jsonObject.getString("deviceId");
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return buildWSFrameString(type, address, function, data);
    }

    private String buildWSFrameString(int type, String address, int function, String data) {
        return WSFrame.builder()
                .type(type)
                .address(address)
                .function(function)
                .data(data)
                .build()
                .getFrameString();
    }

    /**
     * 获取外设信息
     *
     * @return
     */
    @Override
    public String getWSInfo() {
        return buildWSFrameString("AAAAAAAAAAAA", WSFrame.FN_REQUEST_DEVICE_INFO, "");
    }

    /**
     * 获取外设的设备状态
     *
     * @return
     */
    @Override
    public String getWSStatus() {
        return buildWSFrameString(WSFrame.FN_REQUEST_DEVICE_STATUS);
    }

    /**
     * 获取外设故障
     *
     * @return
     */
    @Override
    public String getWSError() {
        return buildWSFrameString(WSFrame.FN_REQUEST_FAULT_INFO);
    }

    /**
     * 停止外设任务执行
     *
     * @return
     */
    @Override
    public String stopWSTask() {
        return buildWSFrameString(WSFrame.FN_QUIT);
    }

    /**
     * 复位命令
     *
     * @return
     */
    @Override
    public String resetTask() {
        return buildWSFrameString(WSFrame.FN_RESET_PARAM);
    }

    /**
     * 获取sim卡信息
     *
     * @return
     */
    @Override
    public String getSimInfo() {
        return buildWSFrameString(WSFrame.FN_SIMJC_HQSIMKZX);
    }

    /**
     * 设置sim卡信息
     *
     * @param simParams
     * @return
     */
    @Override
    public String setSimParams(SimParams simParams) {
        return buildWSFrameString(WSFrame.FN_SIMJC_XFSIMJCCS, simParams.toString());
    }

    /**
     * 获取sim卡检测参数
     *
     * @return
     */
    @Override
    public String getSimCheckInfo() {
        return buildWSFrameString(WSFrame.FN_SIMJC_HQSIMKJCJG);
    }

    /**
     * 电能表整机检测
     *
     * @param zaiboParams
     * @return
     */
    @Override
    public String checkMeterDevice(ZaiboCheckParams zaiboParams) {
        return buildWSFrameString(WSFrame.FN_ZBJC_DNBZJZBJC, zaiboParams.toString());
    }

    /**
     * 采集器整机检测
     *
     * @param zaiboParams
     * @return
     */
    @Override
    public String checkCollectorDevice(ZaiboCheckParams zaiboParams) {
        return buildWSFrameString(WSFrame.FN_ZBJC_CJQZJZBJC, zaiboParams.toString());
    }

    /**
     * 终端/集中器整机检测
     *
     * @param zaiboParams
     * @return
     */
    @Override
    public String checkTerminalDevice(ZaiboCheckParams zaiboParams) {
        return buildWSFrameString(WSFrame.FN_ZBJC_JZQZJZBJC, zaiboParams.toString());
    }

    /**
     * 电能表 模块 检测
     *
     * @param zaiboParams
     * @return
     */
    @Override
    public String checkMeterModule(ZaiboCheckParams zaiboParams) {
        return buildWSFrameString(WSFrame.FN_ZBJC_DNBZBMKJC, zaiboParams.toString());
    }

    /**
     * 采集器 模块 检测
     *
     * @param zaiboParams
     * @return
     */
    @Override
    public String checkCollectorModule(ZaiboCheckParams zaiboParams) {
        return buildWSFrameString(WSFrame.FN_ZBJC_CJQZBMKJC, zaiboParams.toString());
    }

    /**
     * 终端/集中器 模块 检测
     *
     * @param zaiboParams
     * @return
     */
    @Override
    public String checkTerminalModule(ZaiboCheckParams zaiboParams) {
        return buildWSFrameString(WSFrame.FN_ZBJC_JZQZBMKJC, zaiboParams.toString());
    }

    /**
     * 获取环境温度
     *
     * @return
     */
    @Override
    public String getEnvironmentWD() {
        return buildWSFrameString(WSFrame.FN_ENVIR_WD);
    }

    /**
     * 获取环境湿度
     *
     * @return
     */
    @Override
    public String getEnviromentSD() {
        return buildWSFrameString(WSFrame.FN_ENVIR_SD);
    }

    /**
     * 获取电能表误差数据
     *
     * @param params
     * @return
     */
    @Override
    public String getMeterErrorData(MeterErrorParams params) {
        return buildWSFrameString(WSFrame.FN_XCJY_HQDNBWCSJ, params.toString());
    }

    /**
     * 获取电能表谐波数据
     *
     * @param type
     * @return
     */
    @Override
    public String getMeterXieboData(String type) {
        return buildWSFrameString(WSFrame.FN_XCJY_HQDNBXBSJ, type);
    }

    /**
     * 获取电能表接线错误数据
     *
     * @param params
     * @return
     */
    @Override
    public String getMeterLineErrorData(MeterJXCWDataParams params) {
        return buildWSFrameString(WSFrame.FN_XCJY_HQDNBJXCWSJ, params.toString());
    }

    /**
     * 串户检测
     *
     * @param userNo 用户编号
     * @return
     */
    @Override
    public String checkChuanhu(String userNo) {
        return buildWSFrameString(WSFrame.FN_CHJCTQSB_CHJC, userNo);
    }

    /**
     * 进行台区检测 开始
     *
     * @param param 台区识别状态字
     * @return
     */
    @Override
    public String checkTaiquStart(String param) {
        return buildWSFrameString(WSFrame.FN_CHJCTQSB_TQSB_DO, param);
    }

    /**
     * 获取台区识别结果
     *
     * @param mode 台区分支模式
     * @return
     */
    @Override
    public String getTaiquResult(String mode) {
        return buildWSFrameString(WSFrame.FN_CHJCTQSB_TQSB_RESULT, mode);
    }

    /**
     * 获取电能表故障
     *
     * @param meterAddr 被测表地址
     * @return
     */
    @Override
    public String getMeterTrouble(String meterAddr) {
        return buildWSFrameString(WSFrame.FN_GET_METER_COMMON_ERROR, meterAddr);
    }

    /**
     * 设置电能表误差参数
     *
     * @param params
     * @return
     */
    @Override
    public String setErrorParams(SetMeterErrorParams params) {
        return buildWSFrameString(WSFrame.FN_SET_METER_ERROR_PARAMS, params.toString());
    }

    /**
     * 设置电能表误差参数
     *
     * @param params
     * @return
     */
    @Override
    public String setErrorParams(String params) {
        return buildWSFrameString(WSFrame.FN_SET_METER_ERROR_PARAMS, params);
    }

    /**
     * 获取电能表误差检测参数
     *
     * @return
     */
    @Override
    public String getMeterErrorParams() {
        return buildWSFrameString(WSFrame.FN_GET_METER_ERROR_PARAMS);
    }

    /**
     * 检测场强数据
     *
     * @return
     */
    @Override
    public String checkTesla() {
        return buildWSFrameString(WSFrame.FN_CQJC_HQCQJCSJ);
    }

    /**
     * 485参数查询
     *
     * @return
     */
    @Override
    public String get485Params() {
        return buildWSFrameString(WSFrame.FN_RS485_CSCX);
    }

    /**
     * 设置外设485参数
     *
     * @param params
     * @return
     */
    @Override
    public String set485Params(RS485Params params) {
        return buildWSFrameString(WSFrame.FN_RS485_CSSZ, params.toString());
    }

    /**
     * 设置外设485参数
     *
     * @param params
     * @return
     */
    @Override
    public String set485Params(String params) {
        return buildWSFrameString(WSFrame.FN_RS485_CSSZ, params);
    }

    /**
     * epc盘存 2005
     *
     * @param panCun2005
     * @return
     */
    @Override
    public String epcPancun(EpcPanCun2005 panCun2005) {
        return buildWSFrameString(WSFrame.FN_CGP_EPC_PC, panCun2005.toString());
    }

    /**
     * epc 选择标签2006
     *
     * @param choiceLabel2006
     * @return
     */
    @Override
    public String epcChoiceLabel(EpcChoiceLabel2006 choiceLabel2006) {
        return buildWSFrameString(WSFrame.FN_CGP_EPC_CHOICE, choiceLabel2006.toString());
    }

    /**
     * 清空epc选择参数
     *
     * @return
     */
    @Override
    public String epcClearParams() {
        return buildWSFrameString(WSFrame.FN_CGP_EPC_CLEAR);
    }

    /**
     * epc 读取数据
     *
     * @param readData
     * @return
     */
    @Override
    public String epcReadLabelData(EpcReadDataParams2008 readData) {
        return buildWSFrameString(WSFrame.FN_CGP_EPC_DATA, readData.toString());
    }

    /**
     * epc 写入数据
     *
     * @param writeData
     * @return
     */
    @Override
    public String epcWriteLabelData(EpcWriteDataParams2009 writeData) {
        return buildWSFrameString(WSFrame.FN_CGP_EPC_WRITE, writeData.toString());
    }

    /**
     * GB盘存 200C
     *
     * @param panCun
     * @return
     */
    @Override
    public String gbPancun(GBPanCun200C panCun) {
        return buildWSFrameString(WSFrame.FN_CGP_GB_PC, panCun.toString());
    }

    /**
     * GB 选择标签200D
     *
     * @param choiceLabel200D
     * @return
     */
    @Override
    public String gbChoiceLabel(GBChoiceLabel200D choiceLabel200D) {
        return buildWSFrameString(WSFrame.FN_CGP_GB_CHOICE, choiceLabel200D.toString());
    }

    /**
     * 清空GB选择参数
     *
     * @return
     */
    @Override
    public String gbClearParams() {
        return buildWSFrameString(WSFrame.FN_CGP_GB_CLEAR);
    }

    /**
     * GB 读取数据
     *
     * @param readData
     * @return
     */
    @Override
    public String gbReadLabelData(GBReadDataParams200F readData) {
        return buildWSFrameString(WSFrame.FN_CGP_GB_DATA, readData.toString());
    }

    /**
     * GB 写入数据
     *
     * @param writeData
     * @return
     */
    @Override
    public String gbWriteLabelData(GBWriteDataParams2010 writeData) {
        return buildWSFrameString(WSFrame.FN_CGP_GB_WRITE, writeData.toString());
    }

    /**
     * 密钥协商
     *
     * @param secrect 协商类
     * @return
     */
    @Override
    public String secretKey(SecretKeyParams secrect) {
        return buildWSFrameString(WSFrame.FN_MYXS, secrect.toString());
    }

    /**
     * 停止RFID操作
     *
     * @return
     */
    @Override
    public String stopRfid() {
        return buildWSFrameString(WSFrame.FN_CGP_SZGL);
    }

    /**
     * 通用的获取帧数据
     * @param function  功能码
     * @param data 数据域
     * @return
     */
    public String commBuildFrameString(int function, String data){
        if (TextUtils.isEmpty(data)){
            return buildWSFrameString(function);
        }else {
            return buildWSFrameString(function, data);
        }

    }

    /**
     * 设置现场校验仪误差参数设置
     *
     * @param data
     * @return
     */
    @Override
    public String setJyyWcParams(String data) {
        return buildWSFrameString(WSFrame.FN_XCJYY_SETMCWCCS, data);
    }

    /**
     * 获取校验仪误差结果数据
     *
     * @return
     */
    @Override
    public String getJyyWcResult(String taskOnlyNum) {
        return buildWSFrameString(WSFrame.FN_XCJYY_GETMCWCJG, taskOnlyNum);
    }

    /**
     * 设置现场校验仪时间
     *
     * @param data
     * @return
     */
    @Override
    public String setJyyTiming(String data) {
        return buildWSFrameString(WSFrame.FN_XCJYY_SETXCJYYTIME, data);
    }

    /**
     * 设置现场校仪走字误差参数（F1=0x95）
     *
     * @param data
     * @return
     */
    @Override
    public String setJyyZouZiWcParams(String data) {
        return buildWSFrameString(WSFrame.FN_XCJYY_SETZZWC, data);
    }

    /**
     * 请求现场校仪走字误差任务结果（F1=0x96）
     *
     * @return
     */
    @Override
    public String getJyyZouZiWcResult(String taskOnlyNum) {
        return buildWSFrameString(WSFrame.FN_XCJYY_GETZZWC, taskOnlyNum);
    }

    /**
     * 请求现场校仪接线检查数据（F1=0x97）
     *
     * @param data
     * @return
     */
    @Override
    public String getJyyJiexianError(String data) {
        return buildWSFrameString(WSFrame.FN_XCJYY_GETJXWC, data);
    }

    /**
     * 设置现场校验仪日计时误差参数设置（F1=0x98）
     *
     * @param data
     * @return
     */
    @Override
    public String setJyyRijishiParams(String data) {
        return buildWSFrameString(WSFrame.FN_XCJYY_SETRJSWCCS, data);
    }

    /**
     * 请求现场校仪日计时误差数据（F1=0x99）
     *
     * @return
     */
    @Override
    public String getJyyRijishiResult(String taskOnlyNum) {
        return buildWSFrameString(WSFrame.FN_XCJYY_GETRJSWCSJ, taskOnlyNum);
    }



    @Override
    public String getHPLCXxcxData(String data) {
        return buildWSFrameString(WSFrame.FN_HPLC_XXCX, data);
    }

    @Override
    public String getHPLCDnbXxcxData(String data) {
        return buildWSFrameString(WSFrame.FN_HPLC_DNB_XXCX, data);
    }

    @Override
    public String sendHPLCTxgnData(String data) {
        return buildWSFrameString(WSFrame.FN_HPLC_TXGNCS, data);
    }

    @Override
    public String sendHPLCTdsjzdsbData(String data) {
        return buildWSFrameString(WSFrame.FN_HPLC_TDSJZDSN, data);
    }

    @Override
    public String sendHPLCZwcsData(String data) {
        return buildWSFrameString(WSFrame.FN_HPLC_ZWSJCS, data);
    }

    @Override
    public String sendHPLCXtqzwxgcsData(String data) {
        return buildWSFrameString(WSFrame.FN_HPLC_XTQZWXGCS, data);
    }

    @Override
    public String sendHPLCHhxcsData(String data) {
        return buildWSFrameString(WSFrame.FN_HPLC_HHXCS, data);
    }

    @Override
    public String sendHPLCWltptfxData(String data) {
        return buildWSFrameString(WSFrame.FN_HPLC_WLTPXFX, data);
    }

    @Override
    public String getSafeIdentifyDevice() {
        return buildWSFrameString(WSFrame.TYPE_IDENTIFY, WSFrame.FN_ZYAQSB_GETSBSB);
    }

    @Override
    public String setSafeIdentifysTask(String data) {
        return buildWSFrameString(WSFrame.TYPE_IDENTIFY, WSFrame.FN_ZYAQSB_GETRWXF, data);
    }

    @Override
    public String setSafeIdentifySend() {
        return buildWSFrameString(WSFrame.TYPE_IDENTIFY, WSFrame.FN_ZYAQSB_GETYCXX);
    }

}
